import React, { useState, useEffect, useCallback, useMemo } from 'react';

import styles from './pano.css';

/**
 * 不暴露 setState，只能用给得的方法修改状态，更加的安全
 */
function useStateMutations(init: number = 0) {
  const [state, setState] = useState(init);
  return [
    state,
    {
      reset() {
        setState(init);
      },
      increase() {
        setState(v => v + 1);
      },
      decrease() {
        setState(v => v - 1);
      },
      increaseBy(delta: number) {
        return () => setState(v => v + delta);
      },
    },
  ];
}

/**
 * 模拟从外界获取状态并且动态更新
 */
function useSubscription() {
  const [state, setState] = useState(0);
  useEffect(() => {
    const h = setInterval(() => {
      setState(Math.ceil(Math.random() * 100));
    }, 1000);
    return () => {
      clearInterval(h);
    };
  }, []);
  return [state];
}

// 导出 onEvent 的成员，用于组件和DOM元素绑定事件处理函数
function useInput(init: string) {
  const [value, setValue] = useState(init);
  const onChange = useCallback(event => {
    setValue(event.target.value);
  }, []);
  return { value, onChange };
}

/**
 * 全面的示范 hooks 完整机制
 */
export default function() {
  // 基本 local state
  const [basicState, setBasicState] = useState(0);

  // 封装好 setState 的 hooks，只能用指定方法修改状态
  const [protectedState, methods] = useStateMutations(0);

  // 从外界感知状态
  const [subscribedState] = useSubscription();

  const inputBind = useInput('5');

  return (
    <div className={styles.normal}>
      <h1>Page pano</h1>
      <div>
        <span>{protectedState}</span>
        <button onClick={methods.increase}>increase</button>
        <button onClick={methods.decrease}>decrease</button>
        <button onClick={methods.increaseBy(5)}>increase 5</button>
        <button onClick={methods.increaseBy(10)}>increase 5</button>
        <button onClick={methods.increaseBy(+inputBind.value)}>
          increase by {inputBind.value}
        </button>
      </div>
      <div>
        <input {...inputBind} />
      </div>
    </div>
  );
}
